package com.taxi.driver.module.main.home;

import android.os.Handler;
import android.support.v4.app.Fragment;

import com.amap.api.maps.model.LatLng;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.qianxx.utils.RxUtil;
import com.qianxx.utils.SP;
import com.qianxx.view.xrecyclerview.LinearLoading;
import com.socks.library.KLog;
import com.taxi.driver.R;
import com.taxi.driver.common.BasePresenter;
import com.taxi.driver.data.amap.AMapManager;
import com.taxi.driver.data.order.OrderRepository;
import com.taxi.driver.data.user.UserRepository;
import com.taxi.driver.event.MsgEvent;
import com.taxi.driver.event.NetworkEvent;
import com.taxi.driver.event.OrderEvent;
import com.taxi.driver.module.vo.HomePageVO;
import com.taxi.driver.module.vo.MessageVO;
import com.taxi.driver.module.vo.OrderSummaryVO;
import com.taxi.driver.socket.SocketData;
import com.taxi.driver.socket.SocketPushContent;
import com.taxi.driver.util.SpeechUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import javax.inject.Inject;

import rx.functions.Action1;

/**
 * 功能描述：
 */
public class HomePresenter extends BasePresenter implements HomeContract.Presenter {

    private final AMapManager mAMapManager;
    private HomeContract.View mView;
    private OrderRepository mOrderRepository;
    private UserRepository mUserRepository;
    private Handler handler = new Handler();
    private final static int DELAY = 1000 * 60;
    private LinearLoading mLinearLoading;

    private int nowPage = 1;
    private boolean isResume = false;
    private boolean isReported = false;

    private Runnable timeRun = new Runnable() {
        @Override
        public void run() {
            handler.removeCallbacks(timeRun);
            // 获取首页统计信息
            reqWorkInfo();

            handler.postDelayed(timeRun, DELAY);
        }
    };

    @Inject
    public HomePresenter(HomeContract.View view, OrderRepository orderRepository,
                         UserRepository userRepository, AMapManager aMapManager) {
        mView = view;
        mOrderRepository = orderRepository;
        mUserRepository = userRepository;
        mAMapManager = aMapManager;
    }

    @Override
    public void subscribe() {
        super.subscribe();
        if (mFirstSubscribe){
            Double lat = mAMapManager.getLastLocation() == null ? 0d : mAMapManager.getLastLocation().getLatitude();
            Double lng = mAMapManager.getLastLocation() == null ? 0d : mAMapManager.getLastLocation().getLongitude();


            LatLng latLng=new LatLng(lat,lng);
            mSubscriptions.add(
                    mAMapManager.geocodeSearch(latLng).first().compose(RxUtil.applySchedulers())
                            .subscribe(regeocodeAddress -> setAddress(regeocodeAddress.getCity()),
                                    throwable -> KLog.e("=========Throwable===="+throwable.getMessage())));
        }
        // 定时获取首页数据信息
        handler.post(timeRun);
        // 检查是否有进行中订单
        reqHomeStatus();
        // 获取预约单 和可抢订单
        if (!mFirstSubscribe) {
            getAppointmentList();
            canGrapOrders();
        }

        isResume = true;


    }

    @Override
    public void unsubscribe() {
        super.unsubscribe();
        handler.removeCallbacks(timeRun);

        isResume = false;
    }
    private void setAddress(String city) {
//        KLog.e("====="+city);
        new SP(((Fragment) mView).getActivity()).putString("city",city);
    }
    @Override
    public void onCreate() {
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestory() {
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void refresh() {
        mSubscriptions.add(
                mUserRepository.getMsgList(1, 1)
                        .flatMapIterable(entities -> entities)
                        .map(MessageVO::createFrom)
                        .toList()
                        .compose(RxUtil.applySchedulers())
                        .doAfterTerminate(() -> nowPage = 2)
                        .subscribe(vos -> {
                                    mView.setList(vos);
                                    if (!vos.isEmpty() && !isReported) {
                                        isReported = true;
                                        String report = vos.get(0).sendType == 1 ? vos.get(0).content : vos.get(0).title;
                                        if (vos.get(0).status == 1) {
                                            SpeechUtil.speech(((Fragment) mView).getActivity(), report);
                                        }
                                    }
                                },
                                ex -> {
                                    showNetworkError(ex, R.string.network_error, mView);
                                    mView.setListFailed();
                                }));
    }

    @Override
    public void cancelRefresh() {

    }

    @Override
    public void loadMore() {
        mSubscriptions.add(
                mUserRepository.getMsgList(nowPage, 1)
                        .flatMapIterable(entities -> entities)
                        .map(MessageVO::createFrom)
                        .toList()
                        .compose(RxUtil.applySchedulers())
                        .doAfterTerminate(() -> nowPage++)
                        .subscribe(vos -> mView.appendList(vos),
                                ex -> showNetworkError(ex, R.string.network_error, mView)));
    }

    @Override
    public void deleteMsg(int postion, String uuid) {
        mSubscriptions.add(
                mUserRepository.deleteMsg(uuid)
                        .compose(RxUtil.applySchedulers())
                        .doOnSubscribe(() -> mView.showLoadingView(false))
                        .doAfterTerminate(() -> mView.hideLoadingView())
                        .subscribe(entity -> mView.deleteSuccess(postion),
                                ex -> showNetworkError(ex, R.string.network_error, mView, mUserRepository)));
    }

    @Override
    public void reqWorkInfo() {
        mSubscriptions.add(
                mUserRepository.reqWorkInfo()
                        .map(HomePageVO::createFrom)
                        .compose(RxUtil.applySchedulers())
                        .subscribe(vo -> mView.showHomePageInfo(vo),
                                KLog::e));
    }
//获取预约订单
    @Override
    public void getAppointmentList() {
        mSubscriptions.add(
                mOrderRepository.getAppointmentList()
                        .flatMapIterable(entities -> entities)
                        .map(OrderSummaryVO::createFrom)
                        .toList()
                        .compose(RxUtil.applySchedulers())
                        .subscribe(vos -> mView.appointmentList(vos),
                                ex -> showNetworkError(ex, R.string.network_error, mView, mUserRepository)));
    }

    @Override
    public void reqHomeStatus() {
        mView.showBall(true);
        mSubscriptions.add(
                mOrderRepository.reqHomeStatus()
                        .compose(RxUtil.applySchedulers())
                        .doOnNext(entity -> mView.showBall(false))
                        .doOnEach(e -> mView.showBall(false))
                        .subscribe(entity -> mView.showHomeStatus(entity),
                                ex -> showNetworkError(ex, R.string.network_error, mView, mUserRepository)));
    }

    @Override
    public void reqOrderDetail(String orderUuid) {
        mSubscriptions.add(
                mOrderRepository.reqOrderDetail(orderUuid, true)
                        .compose(RxUtil.applySchedulers())
                        .doOnSubscribe(() -> mView.showLoadingView(true))
                        .doAfterTerminate(() -> mView.hideLoadingView())
                        .subscribe(entity -> {
                            if (entity.isOrderOngoing()) { // 跳转进行中订单
                                mView.openOrderOngoing(entity.uuid);
                            } else { // 跳转订单详情
                                mView.openOrderDetail(entity.uuid);
                            }
                        }, ex -> {
                            showNetworkError(ex, R.string.network_error, mView, mUserRepository);
                            mView.reassign();
                        }));
    }

    @Override
    public int driverType() {
        return mUserRepository.getDriverType();
    }

    @Override
    public void canGrapOrders() {
        if (mAMapManager.getLastLocation() != null) {
            mOrderRepository.canGrapOrders(mAMapManager.getLastLocation().getAdCode())
                    .compose(RxUtil.applySchedulers())
                    .subscribe(entity -> mView.showOrderPool(entity.getOrderCount()),
                            KLog::e);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMsgEvent(MsgEvent event) {
        switch (event.type) {
            case MsgEvent.SYSTEM_MESSAGE:
                if (isResume) {
                    SocketData socketData = (SocketData) event.obj1;
                    if (socketData == null)
                        return;
                    if (socketData.msgSendType == 1) {
                        SpeechUtil.speech(((Fragment) mView).getActivity(), socketData.content);
                    } else {
                        SpeechUtil.speech(((Fragment) mView).getActivity(), socketData.title);
                    }
                }
            case MsgEvent.REFRESH_STATUS:
                refresh();
                break;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onOrderEvent(OrderEvent event) {
        switch (event.type) {
            case OrderEvent.ORDER_PUSH:
            case OrderEvent.ORDER_HAS_BEEN_ROBBED:
            case OrderEvent.ORDER_MATCH_THE_TIMEOVER:
                canGrapOrders();
                break;
            case OrderEvent.ORDER_PASSENGER_CANCEL: {
                SocketPushContent content = (SocketPushContent) event.obj1;
                if (content == null)
                    return;
                if (content.data.hasDriver != null && !content.data.hasDriver) {
                    canGrapOrders();
                } else {
                    if (isResume) {
                        mView.orderCancelled(content.data);
                    }
                    getAppointmentList();
                }
                break;
            }
            case OrderEvent.ORDER_CLOSE: {
                SocketPushContent content = (SocketPushContent) event.obj1;
                if (content == null) {
                    return;
                } else {
                    canGrapOrders();
                }
                break;
            }
            case OrderEvent.ORDER_DISTRIBUTE_TO_OTHER: {
                SocketPushContent content = (SocketPushContent) event.obj1;
                if (content == null)
                    return;
                if (isResume) {
                    mView.orderChangedToOther(content.data);
                }
                getAppointmentList();
                break;
            }
            case OrderEvent.ORDER_PASSENGER_ORDER_PAYED:
                if (isResume) {
                    SocketPushContent content = (SocketPushContent) event.obj1;
                    if (content == null)
                        return;
                    SpeechUtil.speech(((Fragment) mView).getActivity(), content.data.report);
                }
                refresh();
                break;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onNetworkEvent(NetworkEvent event) {
        switch (event.type) {
            case NetworkEvent.CONNECT:
                mView.showNetworkNotice(true);
                break;
            case NetworkEvent.DISCONNECT:
                mView.showNetworkNotice(false);
                break;
            case NetworkEvent.SOCKET_SUCCESS:
                mView.showSocketNotice(true);
                break;
            case NetworkEvent.SOCKET_FAILED:
                mView.showSocketNotice(false);
                break;
            case NetworkEvent.LOCATION_SUCCESS:
                mView.showLocationNotice(true);
                break;
            case NetworkEvent.LOCATION_FAILED:
                mView.showLocationNotice(false);
                break;
        }
    }
}
